# -*- coding: utf-8 -*-
import json
import logging
from datetime import datetime, timedelta

from common.bank_record import db as bankrecord_db
from common.mch import db as mch_db
from common.bankcard.model import BANKCARD_TYPE, ISSTATS_TYPE
from common.utils.api import token_required
from common.utils.decorator import response_wrapper
from common.utils.tz import (
    utc_to_local_str
)
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
from decimal import Decimal

_LOGGER = logging.getLogger('hydra')


class BankRecordView(TemplateView):
    def get(self, req):
        query_dct = req.GET.dict()
        _LOGGER.info('BankRecordView get orders: %s, ', query_dct)
        if query_dct.get('transaction_time'):
            transaction_time = json.loads(query_dct['transaction_time'])
            query_dct['transaction_time'] = _transaction_time(transaction_time, query_dct)

        if query_dct.get('payer'):
            query_dct['payer'] = query_dct['payer'].replace(" ", "").replace("\t", "").strip()
            
        card_type = int(query_dct.pop('card_type', BANKCARD_TYPE.RECHARGE))
        is_stats = int(query_dct.pop('is_stats', ISSTATS_TYPE.NOTSTATS))
        items, total_count = bankrecord_db.list_bank_record_card_type(query_dct, card_type)
        mch_names = mch_db.get_mch_name_dict()
        resp_items = []
        check_duplicate = []
        dupe_count = 0
        withdraw_dupe_amount = Decimal(0)
        deposit_dupe_amount = Decimal(0)
        inner_stats = dict()

        for item in items:
            data = item.as_dict()
            check_dupe = str(data['amount']) + str(data['balance']) + data['payer'] + data['transfer_from'] + data['bankcard_num']
            if check_dupe in check_duplicate:
                if data['type'] == 0:
                    withdraw_dupe_amount = withdraw_dupe_amount + data['amount']
                else:
                    deposit_dupe_amount = deposit_dupe_amount + data['amount']
                dupe_count = dupe_count + 1
                continue
            if is_stats == 1:
                stats_info = inner_stats.setdefault(data['bankcard_name'], {})
                stats_info['mch_id'] = mch_names[data['mch_id']]
                stats_info['balance'] = data['balance']
                stats_info['bank'] = data['bank']
                stats_info['bankcard_name'] = data['bankcard_name']
                stats_info['type'] = data['type']
                stats_info['amount'] = stats_info.get('amount', 0) + data.get('amount', 0)
                if data.get('amount', 0) > 0:
                    stats_info['pay_amount'] = stats_info.get('pay_amount', 0) + data.get('amount', 0)
                else:
                    stats_info['withdraw_amount'] = stats_info.get('withdraw_amount', 0) + data.get('amount', 0)
                format_data(data)
            else:
                data['mch_id'] = mch_names[data['mch_id']]
                data['order_id'] = str(data['order_id']) if data['order_id'] else ''
                data['created_at'] = utc_to_local_str(data['created_at'])
                data['updated_at'] = utc_to_local_str(data['updated_at'])
                if data.get('amount', 0) > 0:
                    data['pay_amount'] = str(data.get('amount', 0))
                    data['withdraw_amount'] = ''
                else:
                    data['withdraw_amount'] = str(data.get('amount', 0)).replace('-', '')
                    data['pay_amount'] = ''
                resp_items.append(data)
            check_duplicate.append(check_dupe)

        if is_stats == 1:
            for key, value in inner_stats.items():
                format_data(value)
                resp_items.append(value)
           
        income, spend = bankrecord_db.get_bank_record_overview_card_type(query_dct, card_type)
        if not spend is None and deposit_dupe_amount <> 0:
            income = income - deposit_dupe_amount
        if withdraw_dupe_amount <> 0 and not spend is None:
            spend = spend + withdraw_dupe_amount
        return {'list': resp_items, 'page': query_dct.get('$page', 1),
                'size': len(resp_items), 'total_count': total_count - dupe_count, 'income': income, 'spend': spend}

    @method_decorator(response_wrapper)
    @method_decorator(token_required)
    def dispatch(self, *args, **kwargs):
        return super(BankRecordView, self).dispatch(*args, **kwargs)


def _transaction_time(transaction_time, query_dct):
    start = None
    end = None
    if transaction_time.get('$gte'):
        start = datetime.strptime(transaction_time['$gte'], '%Y-%m-%d %H:%M:%S') + timedelta(hours=8)
    if transaction_time.get('$lt'):
        end = datetime.strptime(transaction_time['$lt'], '%Y-%m-%d %H:%M:%S') + timedelta(hours=8)
    if start and not end:
        query_dct['transaction_time'] = '''{"$gte":"''' + start.strftime('%Y-%m-%d %H:%M:%S') + '''"}'''
    if not start and end:
        query_dct['transaction_time'] = '''{"$lt":"''' + end.strftime('%Y-%m-%d %H:%M:%S') + '''"}'''
    if start and end:
        query_dct['transaction_time'] = '''{"$gte":"''' + start.strftime('%Y-%m-%d %H:%M:%S') + '''","$lt":"''' \
                                        + end.strftime('%Y-%m-%d %H:%M:%S') + '''"}'''
    return query_dct['transaction_time']


def format_data(input_dic, exclude=list()):
    if input_dic and isinstance(input_dic, dict):
        for key, value in input_dic.items():
            if isinstance(value, float) and key not in exclude:
                input_dic.update({key: round(value, 2)})
            if isinstance(value, dict) and key not in exclude:
                format_data(value, exclude)
